﻿//bibaoke.com

using System.Linq;
using Less.Text;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Less.WebBrowserQuery
{
    internal class FilterByAttr : ElementFilter
    {
        internal string Name
        {
            get;
            private set;
        }

        internal string Value
        {
            get;
            private set;
        }

        internal FilterByAttr(string name, string value)
        {
            this.Name = name;
            this.Value = value;
        }

        protected override IEnumerable<HtmlElement> EvalThis(HtmlDocument document)
        {
            if (this.Name.CompareIgnoreCase("name"))
            {
                if (this.Value.IsNotNull())
                {
                    return document.All.GetElementsByName(this.Value).Cast<HtmlElement>();
                }
            }

            return this.GetElementsByAttr(document.All.Cast<HtmlElement>().Where(i => i.Parent.IsNull()));
        }

        protected override IEnumerable<HtmlElement> EvalThis(HtmlDocument document, IEnumerable<HtmlElement> source)
        {
            if (document.IsNotNull())
            {
                if (this.Name.CompareIgnoreCase("name"))
                {
                    if (this.Value.IsNotNull())
                    {
                        HtmlElement[] elements = document.All.GetElementsByName(this.Value).Cast<HtmlElement>().ToArray();

                        return source.SelectMany(i => elements.Where(j => i == j || i.All.Cast<HtmlElement>().Contains(j)));
                    }
                }
            }

            return this.GetElementsByAttr(source);
        }

        private IEnumerable<HtmlElement> GetElementsByAttr(IEnumerable<HtmlElement> source)
        {
            return source.SelectMany(i => i.All.Cast<HtmlElement>().Where(j =>
            {
                if (this.Value.IsNull())
                {
                    return j.GetAttribute(this.Name).IsNotNull();
                }
                else
                {
                    return j.GetAttribute(this.Name) == this.Value;
                }
            }));
        }
    }
}
